

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;

import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.StandardBarPainter;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;

import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.TimeSeriesDataItem;
import org.jfree.ui.RectangleEdge;

import java.awt.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;

public class pieChart {
    static Map<String,Integer> ht = new Hashtable<String,Integer>();
    public static void main(String[] args) {
        ht.put("美国" ,139800);
        ht.put("日本",52900);
        ht.put("德国" ,32800);
        ht.put("中国",30100);
        ht.put("英国",25700);
        ht.put("法国" ,25200);
        ht.put("意大利",20900);
        ht.put("西班牙",14100);
        ht.put("加拿大",13600);
        ht.put("俄罗斯",11400);

        float sum = 0;
        for(Integer i:ht.values()) {
            sum += i;
        }

        //设定数据源
        DefaultPieDataset pieDataset = new DefaultPieDataset();
        DefaultCategoryDataset categoryDataset = new DefaultCategoryDataset();
        //向数据源中插值，第一个参数为名称，第二个参数是double数
        int i = 0;
        for(String nation:ht.keySet()) {
            i++;
            pieDataset.setValue(nation,((float)ht.get(nation))/sum * 100);
            categoryDataset.setValue((float)ht.get(nation),String.valueOf(i),nation);
        }
        //使用ChartFactory来创建JFreeChart
        JFreeChart chart = ChartFactory.createPieChart("2007世界总GDP排名",pieDataset,true,true,true);
        JFreeChart chartD = ChartFactory.createPieChart3D("2007世界总GDP排名",pieDataset,true,true,true);
        JFreeChart chartBarD = ChartFactory.createBarChart3D("收支统计图","国家","数额",categoryDataset, PlotOrientation.VERTICAL,true,false,false);
        JFreeChart chartSeries  = getSeriesChart();
        //设定图片标题
        setPieChart(chart);
        setPieChart(chartD);
        setLineChart(chartBarD);

        //创建文件并将图片地址传递到页面
        outFile(chart,"pie.png");
        outFile(chartD,"pied.png");
        outFile(chartBarD,"chartd.png");
        outFile(chartSeries,"chartSeries.png");
    }

    private static JFreeChart getSeriesChart() {
        //曲线图标题
        String title = "趋势分析";
        //曲线图X轴提示
        String domain = "年份";
        //曲线图Y轴提示
        String range = "GDP";

        //创建时间数据源，每一个TimeSeries在图上是一条曲线
        TimeSeries chinaTs = new TimeSeries("中国");
        Map<Integer, Integer> chinaht = new LinkedHashMap<>();
        chinaht.put(2002,22100);
        chinaht.put(2003,14100);
        chinaht.put(2004,27100);
        chinaht.put(2005,38100);
        chinaht.put(2006,29000);
        chinaht.put(2007,90100);

        for(Integer j:chinaht.keySet()) {
            chinaTs.add(new TimeSeriesDataItem(new Day(1,1,j),chinaht.get(j)));
        }

        //创建时间数据源，每一个TimeSeries在图上是一条曲线
        TimeSeries japanTs = new TimeSeries("日本");
        Map<Integer,Integer> japanht = new LinkedHashMap<>();
        japanht.put(2000,43900);
        japanht.put(2003,63500);
        japanht.put(2004,43400);
        japanht.put(2005,63200);
        japanht.put(2006,53100);
        japanht.put(2007,32900);
        for(Integer j:japanht.keySet()) {
            japanTs.add(new TimeSeriesDataItem(new Day(1,1,j),japanht.get(j)));
        }

        TimeSeries usaTs = new TimeSeries("美国");
        Map<Integer,Integer> usaht = new LinkedHashMap<>();
        usaht.put(2001,100000);
        usaht.put(2003,159800);
        usaht.put(2004,109700);
        usaht.put(2005,129600);
        usaht.put(2006,9800);
        usaht.put(2007,149800);
        for(Integer j:usaht.keySet()) {
            usaTs.add(new TimeSeriesDataItem(new Day(1,1,j),usaht.get(j)));
        }

        TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(chinaTs);
        dataset.addSeries(japanTs);
        dataset.addSeries(usaTs);

        //时间曲线元素
        JFreeChart chart = ChartFactory.createTimeSeriesChart(title,domain,range,dataset,true,true,false);
        setLegend(chart);
        chart.setTitle(new TextTitle(title,new Font("隶书",Font.ITALIC,15)));
        XYPlot plot = (XYPlot) chart.getPlot();
        //是否显示外边框
        plot.setOutlineVisible(false);
        //外边框颜色
        plot.setOutlinePaint(Color.WHITE);
        //白色背景
        plot.setBackgroundPaint(Color.WHITE);
        return chart;
    }

    private static void outFile(JFreeChart chart,String name) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(name);
            ChartUtilities.writeChartAsPNG(out, chart,800,800);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 折线图
     * @param chart
     */
    private static void setLineChart(JFreeChart chart) {
        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        //是否显示外边框
        plot.setOutlineVisible(false);
        //外边框颜色
        plot.setOutlinePaint(Color.WHITE);
        //白色背景
        plot.setBackgroundPaint(Color.WHITE);
        //无数据提示
        plot.setNoDataMessage("无图表数据");
        plot.setNoDataMessageFont(new Font("宋体",Font.BOLD,32));
        //提示字体颜色
        plot.setNoDataMessagePaint(Color.RED);

        //图例
        setLegend(chart);

        //网格线
        plot.setDomainGridlinePaint(Color.BLUE);
        plot.setDomainGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.BLACK);
        plot.setRangeGridlinesVisible(true);

        //横坐标
        CategoryAxis xAxis = plot.getDomainAxis();
        //设置x轴值字体
        xAxis.setTickLabelFont(new Font("宋体",Font.BOLD,25));
        //设置x轴标签字体
        xAxis.setLabelFont(new Font("宋体",Font.BOLD,32));
        //设置x轴线粗细
        xAxis.setAxisLineStroke(new BasicStroke(1f));
        //倾斜
        xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
        //轴线颜色
        xAxis.setAxisLinePaint(Color.BLACK);
        //右边距
        xAxis.setUpperMargin(0.18D);
        //左边距
        xAxis.setLowerMargin(0.1D);

        //纵坐标
        ValueAxis yAxis = plot.getRangeAxis();
        //设置y轴值字体
        yAxis.setTickLabelFont(new Font("宋体",Font.BOLD,25));
        //设置y轴标签字体
        yAxis.setLabelFont(new Font("宋体",Font.BOLD,32));
        //设置y轴线粗细
        yAxis.setAxisLineStroke(new BasicStroke(1f));
        //轴线颜色
        yAxis.setAxisLinePaint(Color.BLACK);
        //上边距
        yAxis.setUpperMargin(0.18D);
        //下边距
        yAxis.setLowerMargin(0.1D);

        //标签数据
        BarRenderer renderer = new BarRenderer();
        //取消渐变效果
        renderer.setBarPainter(new StandardBarPainter());
        //关闭倒影
        renderer.setShadowVisible(false);
        //设置柱子边框可见
        renderer.setDrawBarOutline(false);
        //组内柱子间隔为柱宽的10%
        renderer.setItemMargin(0.03);
        //设置条形柱最大宽度
        renderer.setMaximumBarWidth(0.03);
        //设置条形柱最小宽度
        renderer.setMinimumBarLength(0.03);
        //数据标签格式
        renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        //是否显示数据标签
        renderer.setBaseItemLabelsVisible(true);
        renderer.setItemLabelFont(new Font("宋书",Font.BOLD,32));
        renderer.setSeriesPaint(0,Color.BLUE);
        plot.setRenderer(renderer);
    }

    private static void setLegend(JFreeChart chart) {
        LegendTitle legend = chart.getLegend();
        legend.setPosition(RectangleEdge.BOTTOM);
        legend.setVisible(true);
        legend.setBorder(BlockBorder.NONE);
        legend.setItemFont(new Font("宋体",Font.BOLD,32));
    }

    /**
     * 饼图
     * @param chart
     */
    private static void setPieChart(JFreeChart chart) {
        chart.setTitle(new TextTitle("2007世界总GDP排名",new Font("隶书",Font.ITALIC,15)));
        chart.setBackgroundPaint(Color.white);
        //图例
        setLegend(chart);
        //获得图表显示对象
        PiePlot plot = (PiePlot) chart.getPlot();
        //外边框颜色
        plot.setOutlinePaint(Color.WHITE);
        //白色背景
        plot.setBackgroundPaint(Color.WHITE);
        //无数据提示
        plot.setNoDataMessage("无图表数据");
        //提示字体
        plot.setNoDataMessageFont(new Font("宋体",Font.BOLD,32));
        //提示字体颜色
        plot.setNoDataMessagePaint(Color.RED);
        //是否是正圆
        plot.setCircular(true);
        //图例形状
        plot.setLegendItemShape(new Rectangle(10,10));
        plot.setShadowPaint(Color.WHITE);
        //突出第一个片区
        plot.setExplodePercent(0,0.1D);

        //数据标签
        //设置数据标签字体
        plot.setLabelFont(new Font("宋体",Font.BOLD,32));
        //数据标签背景色
        plot.setLabelBackgroundPaint(Color.WHITE);
        //数据标签数据格式
        plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}"));
        //数据标签外边框颜色
        plot.setLabelOutlinePaint(Color.WHITE);
        //数据标签阴影颜色
        plot.setLabelShadowPaint(Color.WHITE);
        //数据标签最大宽度
        plot.setMaximumLabelWidth(0.2D);
    }
}
